
public class Student {
    // 成员变量 - 使用private修饰符体现封装性
    private String name;
    private int age;
    private String studentId;
    private double gpa;
    
    // 静态变量 - 属于类而不是实例
    private static int totalStudents = 0;
    
    // 无参构造方法
    public Student() {
        // this关键字用于区分成员变量和参数
        this.name = "Unknown";
        this.age = 0;
        this.studentId = "S0000";
        this.gpa = 0.0;
        totalStudents++; // 静态变量属于类，所有实例共享
    }
    
    // 有参构造方法 - 构造方法重载
    public Student(String name, int age, String studentId) {
        // this()调用同类中的其他构造方法，必须放在第一行
        this();
        this.name = name;
        this.age = age;
        this.studentId = studentId;
    }
    
    // 全参构造方法
    public Student(String name, int age, String studentId, double gpa) {
        this(name, age, studentId); // 调用上面的构造方法
        this.gpa = gpa;
    }
    
    // Getter和Setter方法 - 实现封装的关键
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        // 在setter中可以加入验证逻辑
        if (name != null && !name.trim().isEmpty()) {
            this.name = name;
        } else {
            System.out.println("姓名不能为空");
        }
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        // 年龄验证
        if (age > 0 && age < 150) {
            this.age = age;
        } else {
            System.out.println("年龄必须在1-149之间");
        }
    }
    
    public String getStudentId() {
        return studentId;
    }
    
    // studentId一般不允许修改，所以不提供setter
    
    public double getGpa() {
        return gpa;
    }
    
    public void setGpa(double gpa) {
        if (gpa >= 0.0 && gpa <= 4.0) {
            this.gpa = gpa;
        } else {
            System.out.println("GPA必须在0.0-4.0之间");
        }
    }
    
    // 静态方法 - 通过类名直接调用
    public static int getTotalStudents() {
        return totalStudents;
    }
    
    // 普通成员方法
    public void study(String subject) {
        System.out.println(name + "正在学习" + subject);
    }
    
    // 方法重载 - 同名方法不同参数列表
    public void study(String subject, int hours) {
        System.out.println(name + "正在学习" + subject + "，已经学了" + hours + "小时");
    }
    
    // 重写Object类的toString方法
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", studentId='" + studentId + '\'' +
                ", gpa=" + gpa +
                '}';
    }
    
    // 重写Object类的equals方法
    @Override
    public boolean equals(Object obj) {
        // 检查是否为同一对象
        if (this == obj) return true;
        
        // 检查obj是否为null
        if (obj == null) return false;
        
        // 检查类型是否相同
        if (getClass() != obj.getClass()) return false;
        
        // 类型转换
        Student student = (Student) obj;
        
        // 比较关键字段
        return studentId.equals(student.studentId);
    }
}

// 继承示例 - CollegeStudent继承Student
class CollegeStudent extends Student {
    // 子类特有的属性
    private String major;
    private int year;
    
    // 构造方法
    public CollegeStudent(String name, int age, String studentId, String major, int year) {
        // super()调用父类构造方法，必须放在第一行
        super(name, age, studentId);
        this.major = major;
        this.year = year;
    }
    
    // 重写父类方法 - 多态的体现
    @Override
    public void study(String subject) {
        System.out.println("大学生" + getName() + "正在专业学习" + subject);
    }
    
    // 子类特有方法
    public void attendLecture() {
        System.out.println(getName() + "正在参加" + major + "专业的讲座");
    }
    
    // Getter和Setter
    public String getMajor() {
        return major;
    }
    
    public void setMajor(String major) {
        this.major = major;
    }
    
    public int getYear() {
        return year;
    }
    
    public void setYear(int year) {
        this.year = year;
    }
    
    // 重写toString方法
    @Override
    public String toString() {
        return super.toString().replace("}", "") + 
               ", major='" + major + '\'' +
               ", year=" + year +
               '}';
    }
}